package math_utils

type Matrix2 struct {
	M11 ZNumber
	M12 ZNumber
	M21 ZNumber
	M22 ZNumber
}

func MakeMatrix2(other Matrix2) Matrix2 {
	res := Matrix2{}
	res.M11 = other.M11
	res.M12 = other.M12
	res.M21 = other.M21
	res.M22 = other.M22
	return res
}

func MakeMatrix2ByVector2d(v1 Vector2D, v2 Vector2D) Matrix2 {
	res := Matrix2{}
	res.M11 = v1.X
	res.M12 = v1.Y
	res.M21 = v2.X
	res.M22 = v2.Y
	return res
}

func MakeMatrix2ByZNumber(m11 ZNumber, m12 ZNumber, m21 ZNumber, m22 ZNumber) Matrix2 {
	res := Matrix2{}
	res.M11 = m11
	res.M12 = m12
	res.M21 = m21
	res.M22 = m22
	return res
}

func (m Matrix2) Add(other Matrix2) Matrix2 {
	res := Matrix2{}
	res.M11 = m.M11.Add(other.M11)
	res.M12 = m.M11.Add(other.M12)
	res.M21 = m.M11.Add(other.M21)
	res.M22 = m.M11.Add(other.M22)
	return res
}

func (m Matrix2) Sub(other Matrix2) Matrix2 {
	res := Matrix2{}
	res.M11 = m.M11.Sub(other.M11)
	res.M12 = m.M11.Sub(other.M12)
	res.M21 = m.M11.Sub(other.M21)
	res.M22 = m.M11.Sub(other.M22)
	return res
}

func (m Matrix2) Mul(other Matrix2) Matrix2 {
	res := Matrix2{}
	res.M11 = m.M11.Mul(other.M11).Add(m.M12.Mul(m.M21))
	res.M12 = m.M11.Mul(other.M12).Add(m.M12.Mul(m.M22))
	res.M21 = m.M21.Mul(other.M11).Add(m.M22.Mul(m.M21))
	res.M22 = m.M21.Mul(other.M12).Add(m.M22.Mul(m.M22))
	return res
}

func (m Matrix2) MulByZNumber(other ZNumber) Matrix2 {
	res := Matrix2{}
	res.M11 = m.M11.Mul(other)
	res.M12 = m.M12.Mul(other)
	res.M21 = m.M21.Mul(other)
	res.M22 = m.M22.Mul(other)
	return res
}

func (m Matrix2) Eq(other Matrix2) bool {
	return m.M11.Eq(other.M11) && m.M12.Eq(other.M12) && m.M21.Eq(other.M21) && m.M22.Eq(other.M22)
}
